1657E - Star MST - CodeForces Solution


combinatorics dp graph matchings math *2200

Please click on ads to support us..

Python Code:

''' E. Star MST
https://codeforces.com/contest/1657/problem/E
'''

import io, os, sys
input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline  output = sys.stdout.write

DEBUG = os.environ.get('debug') not in [None, '0']

if DEBUG:
    from inspect import currentframe, getframeinfo
    from re import search

def debug(*args):
    if not DEBUG: return
    frame = currentframe().f_back
    s = getframeinfo(frame).code_context[0]
    r = search(r"\((.*)\)", s).group(1)
    vnames = r.split(', ')
    var_and_vals = [f'{var}={val}' for var, val in zip(vnames, args)]
    prefix = f'{currentframe().f_back.f_lineno:02d}: '
    print(f'{prefix}{", ".join(var_and_vals)}')


INF = float('inf')


MOD = 998244353

def precalc_nCk(N, p):
    ''' precompute binomial coefficients to calc up to C(N, N) % p
    C(N, k) mod p = fact[n] * inv_fact[k] * inv_fact[n-k]
    '''
    fact = [1] * (N+1)      for i in range(1, N+1):
        fact[i] = (i * fact[i-1]) % p

    inv_fact = [1] * (N+1)      for i in range(1, N+1):
        inv_fact[i] = pow(fact[i], p-2, p)
    
    return fact, inv_fact



def solve(N, K):
    fact, inv_fact = precalc_nCk(N, MOD)

    dp = [[0]*(K+1) for _ in range(N)]
    dp[0][0] = 1

    for k in range(1, K+1):
        for n in range(N): 
            for i in range(n+1):
                dp[n][k] += fact[n] * inv_fact[i] * inv_fact[n-i] * dp[n-i][k-1] * pow(K-k+1, i*(i-1)//2 + i*(n-i), MOD)
                dp[n][k] %= MOD

    return dp[N-1][K] % MOD


def main():
    N, K = list(map(int, input().split()))
    out = solve(N, K)
    print(out)


if __name__ == '__main__':
    main()

C++ Code:

#include "bits/stdc++.h"

using namespace std;

#define s second
#define f first

typedef long long ll;

typedef pair<ll, ll> pii;

ll dp[253][253] = {0};
ll MOD = 998244353;
// ll pref[253][253];

ll binpow(ll x, ll n, ll m = MOD) {
	assert(n >= 0);
	x %= m;  // note: m * m must be less than 2^63 to avoid ll overflow
	ll res = 1;
	while (n > 0) {
		if (n % 2 == 1) { res = res * x % m; }
		x = x * x % m;
		n /= 2;
	}
	return res;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	ll n, k;

	cin >> n >> k;

	vector<ll> fact(n + 1, 1);
	vector<ll> invfact(n + 1, 1);

	for (ll i = 1; i <= n; i++) {
		fact[i] = (fact[i - 1] * i) % MOD;
		invfact[i] = binpow(fact[i], MOD - 2);
		// cout << i << invfact[i] << endl;
	}

	n--;
	dp[0][0]=1;
	for (ll i = 0; i < n; i++) {
		for (ll j = 0; j <= k; j++) {
			for (ll t = 0; i + t <= n; t++) {
				ll additional = (fact[(i + t)]*((invfact[(i)]*invfact[(t)]) % MOD)) % MOD;
				additional = (additional * binpow((k-j), (t * (i) + t * (t-1) / 2))) % MOD;
				additional = (additional * dp[i][j]) % MOD;
				// cout << i << ' ' << j << ' ' << additional << endl;
				dp[i+t][j+1] = (dp[i+t][j+1] + additional) % MOD;
				// cout << i << j << dp[i][j] << endl;
			}
			// cout << dp[i][j] << ' ';
		}
		// cout << endl;
	}

	ll ans = 0;

	for (ll i = 1; i <= k; i++) {
		ans = (ans + dp[n][i]) % MOD;
	}

	cout << ans << endl;












}


Comments

Submit
0 Comments
More Questions

1382A - Common Subsequence
1512D - Corrupted Array
667B - Coat of Anticubism
284B - Cows and Poker Game
1666D - Deletive Editing
1433D - Districts Connection
2B - The least round way
1324A - Yet Another Tetris Problem
246B - Increase and Decrease
22E - Scheme
1566A - Median Maximization
1278A - Shuffle Hashing
1666F - Fancy Stack
1354A - Alarm Clock
1543B - Customising the Track
1337A - Ichihime and Triangle
1366A - Shovels and Swords
919A - Supermarket
630C - Lucky Numbers
1208B - Uniqueness
1384A - Common Prefixes
371A - K-Periodic Array
1542A - Odd Set
1567B - MEXor Mixup
669A - Little Artem and Presents
691B - s-palindrome
851A - Arpa and a research in Mexican wave
811A - Vladik and Courtesy
1006B - Polycarp's Practice
1422A - Fence